using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using LF.Application.Extend;
using LF.Domain.Entities;
using LF.Domain.Services;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp.DependencyInjection;

namespace LF.Application.Services.Iml
{
    /// <summary>
    /// 权限扫描服务，用于扫描系统中的权限标识并维护到数据库
    /// </summary>
    public class PermissionScannerService : IPermissionScannerService, ITransientDependency
    {
        private readonly IPermissionDbService _permissionDbService;

        public PermissionScannerService(IPermissionDbService permissionDbService)
        {
            _permissionDbService = permissionDbService;
        }

        /// <summary>
        /// 扫描系统内所有使用LFAuthorize特性标记的权限并维护到数据库
        /// </summary>
        public void ScanAndSavePermissions()
        {
            var permissions = ScanPermissions();
            _permissionDbService.SavePermissionsToDatabase(permissions);
        }

        /// <summary>
        /// 扫描系统中的所有LFAuthorize特性
        /// </summary>
        private List<Permission> ScanPermissions()
        {
            var result = new List<Permission>();
            var assemblies = AppDomain.CurrentDomain.GetAssemblies()
                .Where(a => a.FullName.StartsWith("LF."));

            foreach (var assembly in assemblies)
            {
                // 获取所有控制器
                var controllers = assembly.GetTypes()
                    .Where(t => typeof(ControllerBase).IsAssignableFrom(t) ||
                               t.GetCustomAttributes<ApiExplorerSettingsAttribute>().Any());

                foreach (var controller in controllers)
                {
                    // 扫描控制器级别的权限
                    ScanTypePermissions(controller, result);

                    // 扫描方法级别的权限
                    foreach (var method in controller.GetMethods(BindingFlags.Public | BindingFlags.Instance))
                    {
                        ScanMethodPermissions(method, result);
                    }
                }
            }

            return result;
        }

        /// <summary>
        /// 扫描类型(控制器)上的LFAuthorize特性
        /// </summary>
        private void ScanTypePermissions(Type type, List<Permission> permissions)
        {
            var authorizeAttributes = type.GetCustomAttributes<LFAuthorizeAttribute>(true);
            foreach (var attr in authorizeAttributes)
            {
                AddPermission(permissions, attr.DisplayName, attr.PermissionCode);
            }
        }

        /// <summary>
        /// 扫描方法上的LFAuthorize特性
        /// </summary>
        private void ScanMethodPermissions(MethodInfo method, List<Permission> permissions)
        {
            var authorizeAttributes = method.GetCustomAttributes<LFAuthorizeAttribute>(true);
            foreach (var attr in authorizeAttributes)
            {
                AddPermission(permissions, attr.DisplayName, attr.PermissionCode);
            }
        }

        /// <summary>
        /// 添加权限到集合，避免重复
        /// </summary>
        private void AddPermission(List<Permission> permissions, string name, string code)
        {
            if (!permissions.Any(p => p.Code == code))
            {
                permissions.Add(new Permission
                {
                    Id = Guid.NewGuid(),
                    Name = name,
                    Code = code,
                    CreatTime = DateTime.Now,
                    UpdateTime = DateTime.Now
                });
            }
        }
    }
}